How We Saved $500,000 Per Year by Rolling Our Own "S3"
📄 Summarized by Claude Sonnet 4.5
How We Saved $500,000 Per Year by Rolling Our Own "S3"
2025年10月執筆(Miedwar Meshbesher著)
どんなもの?
Nanit社が赤ちゃんの睡眠状態推論を行うビデオ処理パイプラインにおいて、S3の代替としてRustベースのインメモリ型ランディングゾーンN3を構築し、年間約50万ドルのコスト削減を実現
毎秒数千回のアップロードが発生する環境で、S3のPutObjectリクエスト料金がコストの大部分を占め、さらにライフサイクルルールの最小1日制約により、実際には2秒で処理されるオブジェクトに対して24時間分のストレージ料金を支払っていた
N3は通常フロー(ハッピーパス)を処理し、S3はオーバーフローバッファとしてのみ使用する2層フォールバック設計を採用
先行研究と比べてどこがすごい?
クラウドストレージの特性(高可用性・耐久性)に依存せず、短命オブジェクト(数秒の寿命)に特化した専用ソリューションを設計
AWS Network Load Balancerの代わりにRoute53のマルチバリューAレコードを使用したDNS負荷分散により、固定費と従量課金を大幅削減
rustlsによるTLS終端の最適化、Graviton4インスタンスへのアップグレード、target-cpuとcrypto機能を有効化したコンパイルにより、同コストで約30%のRPS向上を実現
TCPタイムスタンプを無効化(net.ipv4.tcp_timestamps=0)し、ACKフレームのオーバーヘッドを削減(各ACKあたり12バイト削減)
技術や手法のキモはどこ?
2コンポーネント設計:
N3-Proxy(ステートレス、TLS終端とルーティング担当)とN3-Storage(ステートフル、インメモリでビデオ保持)を分離し、爆発半径を最小化
DashMapを使用したインメモリストレージ:
Arc<DashMap<Ulid, Bytes>>でビデオを保持し、容量の80%を超えるとアップロードを拒否してOOMを回避
2層フォールバック:
Tier 1(プロキシレベル)はN3-Storageが受け入れ不可の場合にリクエストごとにS3へフォールバック、Tier 2(クラスタレベル)はN3全体が異常時に全トラフィックをS3へリルート
グレースフルシャットダウン:
SIGTERM時にreadinessプローブをNot Readyに設定し、DNS TTLの2倍(60秒)待機してから接続をドレイン、その後再起動
ダウンロード時削除とTTL GCの組み合わせ:
ビデオプロセッサのダウンロード後即座に削除し、処理されずスキップされたセグメントはTTL GCで数時間後にクリーンアップ
どうやって有効だと検証した?
合成ストレステスト:
負荷ジェネレータで同時実行数、低速クライアント、持続的負荷、処理ダウンタイムなど様々な条件下でシステムの限界を調査
ミラーモードによる本番PoC:
n3-proxyが最初にS3に書き込み(本番環境を保持)、次にPoC N3-Storageにも書き込み、カナリアSQSとビデオプロセッサに接続してデータパリティを検証
フィーチャーフラグ(Unleash)によるコホート制御:
ファームウェアバージョンやBaby-UIDリストごとに細かく制御し、問題発生時はデプロイなしでリアルタイムに巻き戻し可能
jemalloc統計とrust-jemalloc-pprofを使用した本番環境でのメモリプロファイリング:
hyperのBytesMutバッファに起因するメモリリークを特定し、keep-aliveの無効化とタイムアウトの厳格化で解決
tcpdumpとtsharkによるACKフレーム分析:
送信バイトの約85%がACKフレームであることを発見し、最適化の根拠を取得
議論はある?
AWSのバースト可能ネットワーキングの制約:
初期ベンチマークで1,000 RPSから約1分後に70 RPSへ低下、ネットワーククレジット枯渇が原因と判明し、c8gn.4xlarge(50 Gbps持続)への移行が必要に
TLSハンドシェイクのオーバーヘッド:
各アップロードで新規接続を開くため、約7KBの証明書を送信、理論的にはECDSA証明書やセッション再開で削減可能だが、カメラ側の変更不要という制約から現状維持
TCPタイムスタンプ無効化のリスク:
高バイト数の同一ソケットでシーケンス番号がラップし、遅延パケットが誤ってマージされて破損する可能性、緩和策として(1)アップロードごとに新規ソケット、(2)n3-proxy↔n3-storage間のソケットを約1GB送信後にリサイクル
スケールと制約の両方が必要:
意味のあるコスト削減のための十分な規模と、シンプルなソリューションを可能にする特定の制約(エフェメラルストレージ、損失耐性、S3フォールバック)の両方が揃って初めて自社構築が正当化される
メンテナンスコストがインフラコスト削減額を下回る必要:
システムの構築と保守のエンジニアリング工数が、削減されるインフラコストより少ない場合のみ意味がある
コスト最適化
クラウド経済性
インメモリアーキテクチャ
Rustパフォーマンス最適化
段階的ロールアウト戦略